<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>592. 分数加减运算</title>
  </head>
  <body>
    <script>
      //     给定一个表示分数加减运算的字符串 expression ，你需要返回一个字符串形式的计算结果。

      // 这个结果应该是不可约分的分数，即最简分数。 如果最终结果是一个整数，例如 2，你需要将它转换成分数形式，其分母为 1。所以在上述例子中, 2 应该被转换为 2/1。

      //

      // 示例 1:

      // 输入: expression = "-1/2+1/2"
      // 输出: "0/1"
      //  示例 2:

      // 输入: expression = "-1/2+1/2+1/3"
      // 输出: "1/3"
      // 示例 3:

      // 输入: expression = "1/3-1/2"
      // 输出: "-1/6"

      // 来源：力扣（LeetCode）
      // 链接：https://leetcode.cn/problems/fraction-addition-and-subtraction
      // 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。

      // 分数相加减
      /**
       * @param {object: {sign: boolean, molecule: number, denominator: number}} fri
       * @param {object: {sign: boolean, molecule: number, denominator: number}} sec
       * @return {string}
       */
      function daFraction(fri, sec) {
        let allDenominator = fri.denominator * sec.denominator // 分母相乘得公共分母
        fri.molecule = fri.molecule * sec.denominator // 通分后 fri 的分子
        sec.molecule = sec.molecule * fri.denominator // 通分后 sec 的分子
        let newMark = {
          sign: true,
          molecule: '',
          denominator: allDenominator,
        }
        if (fri.sign === sec.sign && fri.sign) {
          // 都为正数
          newMark.sign = fri.sign
          newMark.molecule = Number(fri.molecule) + Number(sec.molecule)
        }
        if (fri.sign === sec.sign && !fri.sign) {
          // 都为负数
          newMark.sign = fri.sign
          newMark.molecule = Number(fri.molecule) + Number(sec.molecule)
        }
        if (fri.sign !== sec.sign) {
          // 一正一负
          newMark.sign = Number(fri.molecule) > Number(sec.molecule) ? fri.sign : sec.sign
          newMark.molecule = Math.abs(Number(fri.molecule) - Number(sec.molecule))
        }
        return newMark
      }

      // 最大公约数
      /**
       * @param {number} m
       * @param {number} n
       * @return {string}
       */
      function fn(m, n) {
        let r = m % n
        m = n
        n = r
        if (r == 0) {
          return m
        } else {
          return fn(m, n)
        }
      }

      // 最简分数
      /**
       * @param {object: {sign: boolean, molecule: number, denominator: number}} item
       * @return {string}
       */
      function simpleMark(item) {
        let molecule = Number(item.molecule)
        let denominator = Number(item.denominator)
        let sign = item.sign ? '' : '-'
        if (molecule === 0) {
          return '0/1'
        }
        let n = fn(molecule, denominator)
        return sign + molecule / n + '/' + denominator / n
      }

      /**
       * @param {string} expression
       * @return {string}
       */
      var fractionAddition = function (expression) {
        let i = 0
        let friSign = true // true 代表为正， false 为负
        if (expression[i] === '-') {
          i++
          friSign = false
        }
        let isFrist = true
        let friMark = {
          sign: true, // true 代表为正， false 为负
          molecule: '', // 分子
          denominator: '', // 分母
        }
        while (i < expression.length) {
          let secMark = {
            sign: true,
            molecule: '',
            denominator: '',
          }
          if (isFrist) {
            isFrist = false
            // 获取第一个分数
            friMark.sign = friSign
            while (expression[i] !== '/') {
              // 获取分子
              friMark.molecule += expression[i]
              i++
            }
            i++ // 跳过 /
            while (expression[i] !== '+' && expression[i] !== '-' && i < expression.length) {
              // 获取分母
              friMark.denominator += expression[i]
              i++
            }
          }
          if (i === expression.length) {
            // 只有一个分数时
            break
          }
          // 获取第二个分数
          secMark.sign = expression[i] === '+' ? true : false
          i++ // 跳过 + 或 -
          while (expression[i] !== '/') {
            // 获取分子
            secMark.molecule += expression[i]
            i++
          }
          i++ // 跳过 /
          while (expression[i] !== '+' && expression[i] !== '-' && i < expression.length) {
            // 获取分母
            secMark.denominator += expression[i]
            i++
          }
          friMark = daFraction(friMark, secMark)
        }

        return simpleMark(friMark)
      }

      console.log(fractionAddition('-1/2+1/2'))
    </script>
  </body>
</html>
